/*
 * Copyright The OpenTelemetry Authors
 * SPDX-License-Identifier: Apache-2.0
 */

package com.xiashitech.agent.instrumentation.netty.netty_v4_1.inst;


import com.xiashitech.agent.instrumentation.dubbo.inst.gt27.DubboGt27Handler;
import io.netty.channel.*;
import io.opentelemetry.javaagent.bootstrap.CallDepth;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;

import static net.bytebuddy.matcher.ElementMatchers.*;

public class DefaultChannelPipelineInstrumentation implements TypeInstrumentation {
    // private static final Logger logger = Logger.getLogger("AbstractChannelHandlerContextInstrumentation");

    @Override
    public ElementMatcher<TypeDescription> typeMatcher() {
        // return implementsInterface(named("com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.channel.ChannelOutboundInvoker"));
        return named("io.netty.handler.codec.ByteToMessageDecoder");
    }


    @Override
    public void transform(TypeTransformer transformer) {
        System.out.println("###fff1");
        transformer.applyAdviceToMethod(
                isMethod()
                        .and(named("channelRead"))
                        .and(takesArgument(0, named("io.netty.channel.ChannelHandlerContext")))
                        .and(takesArgument(1, named("java.lang.Object")))
                        .and(takesArguments(2))
                        .and(isPublic()),
                DefaultChannelPipelineInstrumentation.class.getName() + "$ChannelReadAdvice");
        System.out.println("###fff2");

    }

    @SuppressWarnings("unused")
    public static class ChannelReadAdvice {

        @Advice.OnMethodEnter
        public static void onEnter(
                @Advice.Argument(0) ChannelHandlerContext ctx,
                @Advice.Argument(1) Object msg,
                // @Advice.This ChannelPipeline pipeline,
                @Advice.Local("otelCallDepth") CallDepth callDepth
        ) throws Exception {

            // msg ="13552603292";
            System.out.println("###fff3");
           // System.out.println("我是线程" + Thread.currentThread().getName());

            ChannelPipeline pipeline = ctx.pipeline();
            //pipeline.fireChannelRead(msg);
            ChannelHandlerContext ctx2 = DubboGt27Handler.chanelRead(ctx,msg);
           //ChannelHandlerContext ctx2 = ctx.fireChannelRead(msg);
            //pipeline.addLast(ZlibCodecFactory.newZlibEncoder(ZlibWrapper.GZIP));
           // pipeline.addLast(ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP));
           // pipeline.addLast(new CustomNettyDecode());
            //pipeline.addLast("stringServerHandler2", stringServerHandler);

        /*
            pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
            pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
       */


          /*  byte[] bytes2 = "123abc".getBytes(StandardCharsets.UTF_8);
            byteBuf.writeBytes(bytes2);
            ctx.writeAndFlush(byteBuf);*/

            System.out.println("###fff4");
        }

        @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
        public static void onExit() {
            System.out.println("###fff5");
        }
    }


}

